home *** CD-ROM | disk | FTP | other *** search
- ;
- ; This program, originally available on the Motorola DSP bulletin board,
- ; is provided under a DISCLAIMER OF WARRANTY available from Motorola DSP
- ; Operation, 6501 William Cannon Drive, West, Austin, Texas 78735-8598.
- ;
- ident 1,1
- page 132,56,1,1
-
- opt mex,nomd,cex
- ;
- ; Discrete Cosine Transform (DCT)
- ;
- ; V1.2
- ; 03 Oct 88
- ;
- ; The DCT is implemented by using the method described in
- ; "On the Computation of the Discrete Cosine Transform", IEEE
- ; Transactions on Communications. Vol COM-26, No. 6, June 1978
- ;
- ; The operation of this transform is as follows:
- ; 1. Resort the original sequence.
- ; 2. Perform an FFT on the modified sequence.
- ; 3. Multiply the output of the FFT by a complex exponential
- ; and take the real part.
- ; 4. Perform a bit reversed sort to unscramble the result.
- ;
- ; After the transform, the data needs to be scaled (according to
- ; the previously cited reference):
- ; g(0) = g(0)*1.414/N
- ; g(k) = g(k)*2.0/N k=1,2,...,N-1
- ; This scaling is NOT performed by this program. This type of scaling
- ; is application dependent and some implementations may not require
- ; the scaling.
- ;
-
-
- include 'sincos'
- include 'fftr2aa'
-
- start equ $100 ;beginning of program in P memory
- points equ 16 ;number of points in dct
- data equ 0 ;address of data in Y memory
- coef equ 16 ;address of coefficients
-
- sincos points,coef ;generate twiddle factor for FFT.
-
- ; Generate exponential table after twiddle factor table.
- ;
- ; This generates the scale factor of EXP(-j*pi*k/(2*N)).
- ; The real part is in Y memory and the imaginary part is
- ; in X memory. Note that the negative of the part in Y memory
- ; is actually stored so that a -1 (exactly) can be represented
- ; with the fractional arithmetic. This negative sign is
- ; compensated when the actual rotation is performed.
- ;
- rot equ pi/@cvf(2*points)
-
- org x:
- exptbl
- count set 0
- dup points
- dc -@sin(@cvf(count)*rot)
- count set count+1
- endm
-
- org y:
- count set 0
- dup points
- dc -@cos(@cvf(count)*rot)
- count set count+1
- endm
-
-
-
- org p:start
- ;
- ; Do inital sort. The input data is in Y, the sorted data goes to X.
- ; This forms a new sequence in X memory from the sequence in Y memory
- ; according to the definition:
- ; x(k)=y(2k)
- ; x(N-1-K)=x(2k+1) k=0,1,...,N/2-1
- ;
- move #$ffff,m0 ;set linear
- move m0,m4 ;ditto
- move #data,r0 ;point to data
- move #2,n0 ;jump by even numbers
- move r0,r4 ;copy data pointer
- move y:(r0)+n0,a ;get first point
- rep #points/2 ;sort even points
- move y:(r0)+n0,a a,x:(r4)+
- move #data+1,r0 ;point to odds
- move #data+points-1,r4 ;odds output
- move y:(r0)+n0,a ;get first odd
- rep #points/2 ;sort odd points
- move y:(r0)+n0,a a,x:(r4)-
- clr a #data,r0 ;get a zero, point r0 to data
- rep #points ;clear out original data
- move a,y:(r0)+
-
- ;
- ; Do an FFT on the new sequence
- ;
- fftr2aa points,data,coef ;do FFT
-
- ;
- ; Multiply the output by a complex exponential and take the
- ; real part. dct=re[ (a+jb)*(c+jd)] = a*c-b*d where a+jb is the
- ; output of the FFT and c+jd is the rotation factor. Note that
- ; the data is still in bit reversed order but the rotation
- ; table is in sequential order. Thus, the data is accessed with
- ; bit reversed addressing but the rotation table is addressed
- ; with linear addressing.
- ;
- move #exptbl,r0 ;point to exponential table
- move #$ffff,m0 ;linear addressing
-
- move #data,r4 ;point to output of fft
- move r4,r5 ;copy data pointer
- move #0,m4 ;bit reversed addressing
- move m4,m5
- move #points/2,n4
- move n4,n5
-
- move x:(r4),x0 y:(r0),y0 ;get a,-c
- do #points,_gf ;do all points
- mpy -x0,y0,a x:(r0)+,x1 y:(r4)+n4,y1 ;-a*c, get d,b
- macr -x1,y1,a x:(r4),x0 y:(r0),y0 ;-b*d, get a,c
- move a,x:(r5)+n5 ;save dct
- _gf
-
- ;
- ; Bit reverse the output. The rotated and bit reversed data from X
- ; memory is transfered to Y memory and unscrambled. The resulting
- ; DCT is in Y memory starting at DATA with length POINTS.
- ;
- move #data,r0 ;point to data
- move #points/2,n0 ;number of points/2
- move #0,m0 ;set reverse carry
-
- move r0,r4 ;copy pointer
- move #$ffff,m4 ;set linear
-
- move x:(r0)+n0,a ;do preload
- rep #points ;unscramble
- move x:(r0)+n0,a a,y:(r4)+
-
- end
- ^Z
-